#include "level.h"
#include "common.h"
#include "util.h"

// array of directio names. must be consistent with the order of the enum
// in level.h
char *direction_names[] = {
    "north",
    "south",
    "east",
    "west",
    "up",
    "down"
};


// loads a level from a config file and returns a pointer to the starting room
room_t *load_level(char *filename) {
    char buf[2048];
    char *whitespace = " \t\n";
    FILE *levelfile = fopen(filename,"r");

    if(levelfile == NULL) {
        printf("Could not open %s\n", filename);
        exit(1);
    }

    skip_characters(levelfile, whitespace);
    
    // get the total number of rooms
    fgets(buf,256,levelfile);
    num_rooms = atoi(buf);

    skip_characters(levelfile, whitespace);

    // allocate an array for all of the room structs to be stored
	// store the pointer in the global room_array variable
	
	/*** XX YOUR CODE HERE XX ***/
    room_array = (room_t *) malloc(num_rooms * sizeof(room_t));

    // Initialize room_array

	/*** XX YOUR CODE HERE XX ***/
    for (int i = 0; i < num_rooms; i++) {
    	room_t *curr_room = room_array + i;
    	mob_t *mob;
    	mob = (mob_t *) malloc(sizeof(mob_t));
    	mob->count = 0;
    	mob->node = NULL;
    	curr_room->room_id = i;
    	curr_room->description = NULL;
    	for (int j = 0; j < NUM_DIRECTIONS; j++) {
    		curr_room->exits[j].dest = NULL;
    		curr_room->exits[j].locked = false;
    	}
    	curr_room->puzzle.description_fxn = NULL;
    	curr_room->puzzle.interact_fxn = NULL;
    	curr_room->mob = mob;
    }

    skip_characters(levelfile, whitespace);

	// one line at a time, read in room description strings and set 
	// the appropriate field in each string's corresponding room struct
    char *des, *rm; //description and room
    int room_num;
    des = (char *) malloc(256 * sizeof(char));
    rm = (char *) malloc(6 * sizeof(char));		//no room > 999999
    while(fgets(buf, 256, levelfile), buf[0] != '\n') {
	
		/*** XX YOUR CODE HERE XX ***/
    	
		strcpy(des, buf); 
		des[strlen(des) - 1] = '\0';	//strip '\n'
		int i = 0;
		char c = des[i];
		do {
			rm[i] = des[i];
			c = des[++i];
		} while (!(member(c, whitespace)));
		rm[i] = '\0';
		while (member(c, whitespace))
			c = des[++i];
		for (int j = 0; j <= strlen(des); j++)
			des[j] = des[j + i];
		room_num = atoi(rm);
		(room_array + room_num)->description = (char *) malloc((strlen(des) + 1)*sizeof(char));
		strcpy((room_array + room_num)->description, des);
		//free(des);
		//free(rm);
    }

    skip_characters(levelfile, whitespace);

	// hook up rooms so that exits point to each other appropriately.
	// exits should also be set to locked or unlocked as necessary
    while(fgets(buf, 256, levelfile), buf[0] != '\n' && !feof(levelfile)) {
        char *words[32];
        tokenizer(buf, words, " \t\n");
        
		assert(!strcmp("can-go", words[0]) || !strcmp("cant-go", words[0]));
        
		direction dir;
        switch(words[1][0]) {
            case 'n':
                dir = NORTH;
                break;
            case 's':
                dir = SOUTH;
                break;
            case 'e':
                dir = EAST;
                break;
            case 'w':
                dir = WEST;
                break;
            case 'u':
                dir = UP;
                break;
            case 'd':
                dir = DOWN;
                break;
            default:
                printf("%s isn't a direction\n", words[1]);
                assert(false);
        }
		
		/*** YOUR CODE HERE ***/
        int from, to;
        from = atoi(words[2]);
        to = atoi(words[3]);
        (room_array + from)->exits[dir].dest = room_array + to;
       	(room_array + from)->exits[dir].locked = strcmp("can-go", words[0]);
       	//bidirectional
       	dir = flip_direction(dir);
       	(room_array + to)->exits[dir].dest = room_array + from;
       	(room_array + to)->exits[dir].locked = false;
     }

    return room_array; // equivalent to a pointer to the first element of the array
}

